<template>
  <div id="monaco" style="width: 100%;height: calc(100% - 60px);margin-top: 30px;">
    <div class="btns">
      <el-button type="primary" size="medium" @click="copy">复制</el-button>
      <el-button type="primary" size="medium" @click="paste">粘贴</el-button>
    </div>
  </div>
</template>

<script>
import * as monaco from 'monaco-editor'
export default {
  props: {
    value: {
      type: Object
    }
  },
  data () {
    return {
      editor: null
    }
  },
  mounted () {
    this.initEditor()
  },
  methods: {
    initEditor () {
      this.editor = monaco.editor.create(document.getElementById("monaco"), {
        value: this.value.value, // 编辑器初始显示文字
        language: this.value.type, // 设置语言
        // automaticLayout: true, // 是否自适应宽高|自动布局，设置为true的话会有性能问题，也可以使用 this.editor.layout()
        // foldingStrategy: 'indentation', // 代码可分小段折叠
        // autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"
        // autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"
        // autoIndent: 'None', // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
        // comments: {// 注释配置
        //   ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。
        //   insertSpace: true // 在行注释标记之后和块注释标记内插入一个空格。默认为真。
        // },
        // cursorBlinking: 'Solid', // 光标动画样式
        // cursorSmoothCaretAnimation: true, // 是否启用光标平滑插入动画  当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置
        // cursorSurroundingLines: 0, // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中
        // cursorSurroundingLinesStyle: 'all', // "default" | "all" 光标环绕样式
        // cursorWidth: 2, // <=25 光标宽度
        // overviewRulerBorder: true, // 是否应围绕概览标尺绘制边框
        theme: 'vs-dark', // 主题: 也可以使用 editor.setTheme('vs') vs, hc-black, or vs-dark
        folding: true, // 是否启用代码折叠
        // scrollBeyondLastLine: false, // 设置编辑器是否可以滚动到最后一行之后
        // renderLineHighlight: 'all', // 当前行突出显示方式  "all" | "line" | "none" | "gutter"
        // scrollbar: { // 滚动条宽高
        //   verticalScrollbarSize: 8,
        //   horizontalScrollbarSize: 8,
        // },
        // minimap: {
        //   enabled: true // 启用预览图
        // },
        // formatOnPaste: true,
        // renderValidationDecorations: 'on',
        // readOnly: false, // 是否只读
        // lineNumbers: true, // 是否显示行数
        lineHeight: 20, // 行高
        tabSize: 2, // 缩进
        fontSize: 16, // 字体大小
        // glyphMargin: true, // 字形边缘
        // acceptSuggestionOnCommitCharacter: true, // 接受关于提交字符的建议
        // acceptSuggestionOnEnter: 'on', // 接受输入建议 "on" | "off" | "smart" 
        // accessibilityPageSize: 10, // 辅助功能页面大小 Number 说明：控制编辑器中可由屏幕阅读器读出的行数。警告：这对大于默认值的数字具有性能含义。
        // accessibilitySupport: 'on', // 辅助功能支持 控制编辑器是否应在为屏幕阅读器优化的模式下运行。
        // autoClosingOvertype: 'always', // 是否关闭改写 即使用insert模式时是覆盖后面的文字还是不覆盖后面的文字 "always" | "never" | "auto"
        // autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"
        // codeLens: false, // 是否显示codeLens 通过 CodeLens，你可以在专注于工作的同时了解代码所发生的情况 – 而无需离开编辑器。 可以查找代码引用、代码更改、关联的 Bug、工作项、代码评审和单元测试。
        // codeLensFontFamily: '', // codeLens的字体样式
        // codeLensFontSize: 14, // codeLens的字体大小
        // colorDecorators: false, // 呈现内联色彩装饰器和颜色选择器
        // contextmenu: true, // 启用上下文菜单
        // columnSelection: false, // 启用列编辑 按下shift键位然后按↑↓键位可以实现列选择 然后实现列编辑
        // autoSurround: 'never', // 是否应自动环绕选择
        // copyWithSyntaxHighlighting: true, // 是否应将语法突出显示复制到剪贴板中 即 当你复制到word中是否保持文字高亮颜色
        // cursorStyle: 'UnderlineThin', // "Block"|"BlockOutline"|"Line"|"LineThin"|"Underline"|"UnderlineThin" 光标样式
        // links: true, // 是否点击链接
        // roundedSelection: false, // 选区是否有圆角
        wordWrap: 'on', // 是否自动换行
      })


      /**
       * Event
      */
      // 内容改变事件
      this.editor.onDidChangeModelContent(event => {
        this.$emit('update:value', {
          type: this.value.type,
          // 获取编辑器内容：this.editor.getValue()
          value: this.editor.getValue()
        })

        // 打断点
        this.$nextTick(() => {
          let pos = this.editor.getPosition()
          if (pos) {
            //获取当前的行
            let line = pos.lineNumber
            //如果当前行的内容为空，删除断点（空行不允许设置断点，我自己规定的，，，）
            // if (this.editor.getModel().getLineContent(line).trim() === '') {
            //   this.removeBreakPoint(line)
            // } else {
            //   //如果当前行存在断点，删除多余的断点只保留一个
            //   if (this.hasBreakPoint(line)) {
            //     this.removeBreakPoint(line)
            //     this.addBreakPoint(line)
            //   }
            // }
            this.addBreakPoint(line)
          }
        })
      })
      // 失去焦点事件
      this.editor.onDidBlurEditorText(event => {
        // console.info("失去编辑焦点")
        // this.editor.setLanguage('java')
      })
      // 实时获取光标所在行号和列号
      this.editor.onDidChangeCursorPosition(event => {
        // console.log('行号: ', this.editor.getPosition().lineNumber)
        // console.log('列: ', this.editor.getPosition().column)
      })


      /**
       * 定义自定义主题
      */
      // monaco.editor.defineTheme('myTheme', {
      //   base: 'vs',
      //   inherit: true,
      //   rules: [{ background: 'EDF9FA' }],
      // })
      // 使用主题
      // this.editor.setTheme('myTheme')


      /**
       * 语言languages
      */
      // 获取语言列表 monaco.languages.getLanguages()


      /**
       * Model
      */
      // console.log(this.editor.getModel())


      /**
       * Command
      */
      // 自定义快捷键： ctrl + s保存
      // monaco.KeyCode.KeyS: 快捷键
      this.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
        console.log('SAVE pressed!')
      })
      this.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK, function () {
        console.log('key pressed!')
      })

      /**
       * Actions
      */
      // console.log(this.editor.getActions())


      // 打断点
      this.$nextTick(() => {
        console.log(document.querySelectorAll('.line-numbers'))
        console.log(document.querySelector('.margin-view-overlays').querySelectorAll('div.line-numbers'))
        document.querySelector('.margin-view-overlays').querySelectorAll('div.line-numbers').forEach(item => {
          console.log(item)
        })
      })
    },
    //添加断点
    async addBreakPoint (line) {
      console.log(line)
      let model = this.editor.getModel()
      // if (!model) return
      let value = {
        range: new monaco.Range(line, 1, line, 1),
        options: {
          isWholeLine: true,
          linesDecorationsClassName: 'breakpoints-fake'
        }
      }
      model.deltaDecorations([], [value])
    },
    // 复制：触发编辑器操作实现复制/粘贴功能
    copy () {
      this.editor.trigger('source','editor.action.clipboardCopyAction')
    },
    // 粘贴
    paste () {
      console.log('发数据咯')
    },
  },
  beforeDestroy () {
    // 销毁
    this.editor.dispose()
  }
}
</script>

<style lang="scss">
#monaco {
  position: relative;
  .btns {
    position: absolute;
    right: 0;
    top: -40px;
  }
  .breakpoints-fake{
    background: rgba(255, 0, 0, 0.6);
    width: 10px !important;
    height: 10px !important;
    left: 8px !important;
    top: 5px;
    border-radius: 5px;
  }
}
</style>